#include "textedit.h"
#include <QFile>
#include <QFileInfo>
#include <QTextCodec>
#include <QFileDialog>
#include <QTextDocumentWriter>
#include <QMessageBox>
#include <QCloseEvent>

int TextEdit::docNo = 1;

TextEdit::TextEdit(QWidget *parent): QTextEdit(parent),
    docWindowTitle(""), docFilePath("")
{
    setAttribute(Qt::WA_DeleteOnClose);    //关闭的时候被释放
}

TextEdit::~TextEdit()
{
}

void TextEdit::initNewDoc()
{
    docWindowTitle = QString("文档 %1").arg(docNo++);
    //使用windowModified机制，添加[*]占位符
    //当窗口中显示的文档有未保存的更改，*号显示出来
    setWindowTitle(docWindowTitle + "[*]");

    //document() 返回当前TextEdit内的文档
    connect(document(), &QTextDocument::contentsChanged, this, &TextEdit::setWindowModify);
}

QString TextEdit::getDocFilePath() const
{
    return docFilePath;
}

QString TextEdit::getDocName() const
{
    //获取文件名
    return QFileInfo(docFilePath).fileName();
}

QString TextEdit::getDocWindowTitle() const
{
    return docWindowTitle;
}

bool TextEdit::loadDoc(const QString &docName)
{
    if(!docName.isEmpty())
    {
        QFile file(docName);
        if(!file.exists()) return false;        //文件不存在
        if(!file.open(QFile::ReadOnly)) return false;     //打开文件失败

        QByteArray text = file.readAll();   //读取文件内容

        if(Qt::mightBeRichText(text))       //如果是富文本
        {
            setHtml(text);            //富文本显示
        }
        else
        {
            //纯文本：只存储文字内容，不存储文字样式
            setPlainText(text);       //纯文本显示
        }

        initOpenDoc(docName);       //初始化打开的文档
    }
    return true;
}

void TextEdit::initOpenDoc(const QString &docName)
{
    docFilePath = QFileInfo(docName).canonicalFilePath();     //返回文件绝对路径，包含文件名
    docWindowTitle = getDocName() + " " + QString::number(docNo++);
    setWindowTitle(docWindowTitle + "[*]");

    //document() 返回当前TextEdit内的文档
    connect(document(), &QTextDocument::contentsChanged, this, &TextEdit::setWindowModify);
}

bool TextEdit::saveDoc()
{
    if(document()->isModified())        //如果文档被修改
    {
        if(!docFilePath.isEmpty())      //如果文档路径不为空
            return writeToDoc(docFilePath);     //直接写入本地文件
        else
            return saveAsDoc();         //另存为
    }
    return false;
}

bool TextEdit::saveAsDoc()
{
    //返回用户选择的文件名（路径+文件名）。该文件不必存在。
    QString docName = QFileDialog::getSaveFileName(this, "另存为", "../", "HTML文档(*.html);;文本文件(*.txt)");

    if(docName.isEmpty()) return false;
    return writeToDoc(docName);
}

bool TextEdit::writeToDoc(const QString &docName)
{
    //QTextDocumentWriter类用于将QTextDocument写入文件或其他设备
    QTextDocumentWriter docWriter(docName);   //如果没有提供format, QTextDocumentWriter将通过检查fileName的扩展名来检测文档格式
    if(docWriter.write(this->document()))
    {
        /*if(docFilePath.isEmpty()) */docFilePath = QFileInfo(docName).canonicalFilePath();
        document()->setModified(false);  //文档未改动
        setWindowModified(false);        //窗口不显示占位符标识
    }

    return true;
}

bool TextEdit::promptSave()
{
    if(!document()->isModified()) return true;

    QMessageBox::StandardButton res;
    res = QMessageBox::warning(this, "提示", QString("%1已修改，是否保存？").arg(docWindowTitle),
                               QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);

    if(res == QMessageBox::Yes)
    {
        return saveDoc();
    }
    else if(res ==  QMessageBox::No)
    {
        return true;
    }
    else if(res == QMessageBox::Cancel)
    {
        return false;
    }
}

void TextEdit::closeEvent(QCloseEvent *event)
{
    if(promptSave())
    {
        event->accept();
    }
    else
    {
        event->ignore();
    }
}

void TextEdit::setWindowModify()
{
    //isModified()返回文档是否已被用户修改
    setWindowModified(document()->isModified());
}
